Skip to content

fix(audience): prevent IL2CPP stripping of Unity hooks assembly#790

Merged
nattb8 merged 1 commit into
mainfrom
feat/sdk-480-il2cpp-stripping
Jun 10, 2026
Merged

fix(audience): prevent IL2CPP stripping of Unity hooks assembly#790
nattb8 merged 1 commit into
mainfrom
feat/sdk-480-il2cpp-stripping

Conversation

@nattb8

@nattb8 nattb8 commented Jun 9, 2026

Copy link
Copy Markdown
Collaborator

Fixes SDK-480.

Problem

Games built with IL2CPP + High stripping silently lose all Unity context fields (userAgent, locale, screen, timezone) from every event. The linker strips the entire Immutable.Audience.Unity assembly when it finds no call sites into it — so the [RuntimeInitializeOnLoadMethod] hook never fires and ContextProvider is never registered. Only library and libraryVersion survive because they come from Immutable.Audience.Runtime, which has direct references keeping it alive.

The SDK ships a link.xml to guard against this, but Unity's linker skips it for packages loaded via a file: path outside the project tree. Studios without a project-level link.xml fallback hit this silently.

Confirmed in production on project 18282: ~97% of 0.3.0 events are missing userAgent. All 0.2.2 events from the same project had it — the regression correlates with them switching to an IL2CPP + High stripping build around the 0.3.0 upgrade.

Fix

Two lines in AudienceUnityHooks.cs:

  • [assembly: AlwaysLinkAssembly] — forces the linker to process the assembly regardless of call sites
  • [Preserve] on the class — keeps Install() alive once the assembly is included

[Preserve] alone is not enough: if the linker skips the assembly entirely, it never evaluates the attribute.

Test plan

  • Build example app with IL2CPP + High stripping and no audience lines in link.xml
  • Confirm events include full context (userAgent, locale, screen, timezone)
  • Confirm no PersistentDataPath is required crash on init

Games using IL2CPP with High stripping and no project-level link.xml
lose all Unity context fields (userAgent, locale, screen, timezone).
The linker strips Immutable.Audience.Unity entirely when it finds no
call sites, so the [RuntimeInitializeOnLoadMethod] hooks never fire and
ContextProvider is never registered.

[assembly: AlwaysLinkAssembly] forces the linker to process the assembly
regardless of call sites. [Preserve] on AudienceUnityHooks keeps Install()
alive once the assembly is included. [Preserve] alone is insufficient
because the linker skips the assembly before evaluating attributes.

Fixes SDK-480.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@nattb8 nattb8 requested review from a team as code owners June 9, 2026 08:31
@nattb8 nattb8 merged commit 9bc8421 into main Jun 10, 2026
134 of 174 checks passed
@nattb8 nattb8 deleted the feat/sdk-480-il2cpp-stripping branch June 10, 2026 00:14
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Development

Successfully merging this pull request may close these issues.

2 participants